"""主应用入口 - 集成式多层记忆架构AI系统"""

import asyncio
import signal
import sys
from pathlib import Path
from typing import Dict, Any, Optional
from loguru import logger

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from src.config import load_config
from src.database.manager import DatabaseManager
from src.core.context_orchestrator import ContextOrchestrator
from src.mcp.server import MCPServer
from src.mcp.stdio_handler import StdioHandler
from src.mcp.websocket_handler import WebSocketHandler


class MCPApplication:
    """MCP应用主类"""
    
    def __init__(self, config_path: Optional[str] = None):
        # 加载配置
        self.config = load_config(config_path)
        
        # 配置日志
        self._setup_logging()
        
        # 初始化组件
        self.db_manager = None
        self.orchestrator = None
        self.mcp_server = None
        self.stdio_handler = None
        self.websocket_handler = None
        
        # 运行状态
        self.is_running = False
        self.shutdown_event = asyncio.Event()
        
        logger.info("MCP应用已创建")
    
    def _setup_logging(self):
        """配置日志系统"""
        log_config = self.config.get('logging', {})
        
        # 移除默认处理器
        logger.remove()
        
        # 控制台日志
        console_level = log_config.get('console_level', 'INFO')
        logger.add(
            sys.stderr,
            level=console_level,
            format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
            colorize=True
        )
        
        # 文件日志
        if log_config.get('file_enabled', True):
            log_file = log_config.get('file_path', 'logs/mcp_app.log')
            file_level = log_config.get('file_level', 'DEBUG')
            
            # 确保日志目录存在
            Path(log_file).parent.mkdir(parents=True, exist_ok=True)
            
            logger.add(
                log_file,
                level=file_level,
                format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
                rotation=log_config.get('rotation', '10 MB'),
                retention=log_config.get('retention', '7 days'),
                compression="zip"
            )
        
        logger.info("日志系统已配置")
    
    async def initialize(self):
        """初始化应用"""
        try:
            logger.info("开始初始化MCP应用...")
            
            # 1. 初始化数据库管理器
            logger.info("初始化数据库管理器...")
            self.db_manager = DatabaseManager(self.config)
            await self.db_manager.initialize()
            
            # 2. 初始化上下文编排器
            logger.info("初始化上下文编排器...")
            self.orchestrator = ContextOrchestrator(self.config)
            await self.orchestrator.initialize()
            
            # 3. 初始化MCP服务器
            logger.info("初始化MCP服务器...")
            self.mcp_server = MCPServer(self.orchestrator, self.config)
            
            # 4. 初始化处理器
            connection_config = self.config.get('connection', {})
            
            # Stdio处理器
            if connection_config.get('stdio', {}).get('enabled', True):
                logger.info("初始化Stdio处理器...")
                self.stdio_handler = StdioHandler(self.mcp_server, self.config)
            
            # WebSocket处理器
            if connection_config.get('websocket', {}).get('enabled', False):
                logger.info("初始化WebSocket处理器...")
                self.websocket_handler = WebSocketHandler(self.mcp_server, self.config)
            
            logger.info("MCP应用初始化完成")
            
        except Exception as e:
            logger.error(f"初始化MCP应用失败: {e}")
            await self.cleanup()
            raise
    
    async def start(self):
        """启动应用"""
        try:
            if self.is_running:
                logger.warning("应用已在运行")
                return
            
            logger.info("启动MCP应用...")
            
            # 启动MCP服务器
            await self.mcp_server.start()
            
            # 启动处理器
            start_tasks = []
            
            if self.stdio_handler:
                start_tasks.append(self.stdio_handler.start())
            
            if self.websocket_handler:
                start_tasks.append(self.websocket_handler.start())
            
            if start_tasks:
                await asyncio.gather(*start_tasks)
            
            self.is_running = True
            logger.info("MCP应用启动成功")
            
            # 设置信号处理
            self._setup_signal_handlers()
            
        except Exception as e:
            logger.error(f"启动MCP应用失败: {e}")
            await self.stop()
            raise
    
    async def stop(self):
        """停止应用"""
        try:
            if not self.is_running:
                logger.warning("应用未在运行")
                return
            
            logger.info("停止MCP应用...")
            
            # 停止处理器
            stop_tasks = []
            
            if self.stdio_handler:
                stop_tasks.append(self.stdio_handler.stop())
            
            if self.websocket_handler:
                stop_tasks.append(self.websocket_handler.stop())
            
            if stop_tasks:
                await asyncio.gather(*stop_tasks, return_exceptions=True)
            
            # 停止MCP服务器
            if self.mcp_server:
                await self.mcp_server.stop()
            
            self.is_running = False
            self.shutdown_event.set()
            
            logger.info("MCP应用已停止")
            
        except Exception as e:
            logger.error(f"停止MCP应用失败: {e}")
    
    async def cleanup(self):
        """清理资源"""
        try:
            logger.info("清理应用资源...")
            
            # 清理组件
            cleanup_tasks = []
            
            if self.orchestrator:
                cleanup_tasks.append(self.orchestrator.shutdown())
            
            if self.db_manager:
                cleanup_tasks.append(self.db_manager.shutdown())
            
            if cleanup_tasks:
                await asyncio.gather(*cleanup_tasks, return_exceptions=True)
            
            logger.info("应用资源清理完成")
            
        except Exception as e:
            logger.error(f"清理应用资源失败: {e}")
    
    def _setup_signal_handlers(self):
        """设置信号处理器"""
        def signal_handler(signum, frame):
            logger.info(f"接收到信号 {signum}，开始优雅关闭...")
            asyncio.create_task(self.stop())
        
        # 注册信号处理器
        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)
        
        # Windows特定信号
        if sys.platform == "win32":
            signal.signal(signal.SIGBREAK, signal_handler)
    
    async def run(self):
        """运行应用（主循环）"""
        try:
            # 初始化
            await self.initialize()
            
            # 启动
            await self.start()
            
            # 等待关闭信号
            logger.info("MCP应用正在运行，按 Ctrl+C 停止...")
            await self.shutdown_event.wait()
            
        except KeyboardInterrupt:
            logger.info("接收到键盘中断信号")
        except Exception as e:
            logger.error(f"运行应用时发生错误: {e}")
        finally:
            # 清理
            await self.cleanup()
    
    async def health_check(self) -> Dict[str, Any]:
        """健康检查"""
        try:
            if not self.orchestrator:
                return {
                    "healthy": False,
                    "status": "not_initialized",
                    "message": "应用未初始化"
                }
            
            # 检查各组件健康状态
            health = await self.orchestrator.health_check()
            
            # 检查处理器状态
            handlers_status = {}
            
            if self.stdio_handler:
                handlers_status["stdio"] = await self.stdio_handler.health_check()
            
            if self.websocket_handler:
                handlers_status["websocket"] = await self.websocket_handler.health_check()
            
            health["handlers"] = handlers_status
            health["application_running"] = self.is_running
            
            return health
            
        except Exception as e:
            logger.error(f"健康检查失败: {e}")
            return {
                "healthy": False,
                "status": "error",
                "error": str(e)
            }
    
    async def get_stats(self) -> Dict[str, Any]:
        """获取应用统计信息"""
        try:
            if not self.orchestrator:
                return {"error": "应用未初始化"}
            
            # 获取核心统计
            stats = await self.orchestrator.get_stats()
            
            # 添加应用级统计
            stats["application"] = {
                "running": self.is_running,
                "config": {
                    "connection_types": [],
                    "database_types": list(self.config.get('database', {}).keys())
                }
            }
            
            # 添加连接类型
            if self.stdio_handler:
                stats["application"]["config"]["connection_types"].append("stdio")
            
            if self.websocket_handler:
                stats["application"]["config"]["connection_types"].append("websocket")
            
            return stats
            
        except Exception as e:
            logger.error(f"获取应用统计失败: {e}")
            return {"error": str(e)}


async def main():
    """主函数"""
    try:
        # 创建应用实例
        app = MCPApplication()
        
        # 运行应用
        await app.run()
        
    except Exception as e:
        logger.error(f"应用运行失败: {e}")
        sys.exit(1)


if __name__ == "__main__":
    # 运行应用
    asyncio.run(main())